home *** CD-ROM | disk | FTP | other *** search
- /*
- * Blob Manager Demonstration: Hangman - the classic game
- *
- * This module is a little unusual in that it doesn't use BlobClick.
- * The user chooses letters simply by clicking on them and the
- * scenario in effect drags the letters to the receptors itself.
- *
- * 26 July 1986 Paul DuBois
- */
-
- # include "TransSkel.h"
-
- # include "BlobMgr.h"
- # include "BlobDemo.h"
-
-
- # define hWord 10 /* horizontal position of word to find */
- # define vWord 5 /* vertical position */
- # define hLetters 10 /* location of letter pool */
- # define vLetters 35
- # define vMesg 85
- # define vMan 75
-
- # define letterSize 18 /* size of letter blobs */
- # define letterGap 2 /* gap between blobs */
-
-
- static WindowPtr wind;
- static ControlHandle button;
-
-
- static BlobSetHandle letters = nil; /* donor blobs */
- static BlobSetHandle word = nil; /* word to be found */
-
- static Boolean pause;
- static short wrongMoves;
- static short hMid;
- static Str255 statusStr = "\p";
-
-
- static void
- StatusMesg (StringPtr s)
- {
- Rect r;
-
- SetRect (&r, hMid - 45, vMesg, hMid + 45, vMesg + 20);
- TextBox (s+1, (long) s[0], &r, teJustCenter);
- StrCpy (statusStr, s);
- }
-
-
- /*
- * Make donor blobs.
- */
-
- static void
- MakeDonors (void)
- {
- short i, j, h, v;
-
- letters = NewBlobSet ();
- v = vLetters;
- for (i = 0; i < 2; ++i)
- {
- h = hLetters;
- for (j = 0; j < 13; ++j)
- {
- (void) MakeCharBlob (letters, true, infiniteGlue, false,
- h, v, i * 13 + j + 'a');
- h += letterSize + letterGap;
- }
- v += letterSize + letterGap;
- }
- }
-
-
- /*
- * Generate a new problem to solve: get a word from the word picker.
- */
-
- static void
- GenerateProblem (void)
- {
- BlobHandle b;
- char *s;
- short i;
- short h;
-
- /* get rid of any old word blob set */
-
- if (word != nil)
- {
- HideBlobSet (word);
- DisposeBlobSet (word);
- }
- word = NewBlobSet ();
- s = (char *) PickWord ();
-
- /* create new blob set, attach match information */
-
- h = hMid - (s[0] * (letterSize + letterGap) - letterGap) / 2;
- for (i = 1; i <= s[0]; ++i)
- {
- b = MakeCharBlob (word, true, 0, true, h, vWord, ' ');
- NewBlobMatch (GetBlobHandle (letters, s[i] - 'a'), b);
- h += letterSize + letterGap;
- }
- }
-
-
- static void
- OneDrawMan (short h, short v) /* h,v is point at top of man's head */
- {
- Rect r;
- PenState ps;
-
- if (wrongMoves == 0) /* erase man */
- {
- wrongMoves = 7; /* draw entire man in bit-clear mode */
- GetPenState (&ps);
- PenMode (patBic);
- OneDrawMan (h, v);
- wrongMoves = 0;
- SetPenState (&ps);
- return;
- }
- SetRect (&r, h - 6, v, h + 7, v + 16);
- FrameOval (&r);
- if (wrongMoves == 1) return;
- MoveTo (h, v + 16);
- LineTo (h, v + 20);
- if (wrongMoves == 2) return;
- LineTo (h - 16, v + 32);
- if (wrongMoves == 3) return;
- MoveTo (h, v + 20);
- LineTo (h + 16, v + 32);
- if (wrongMoves == 4) return;
- MoveTo (h, v + 20);
- LineTo (h, v + 40);
- if (wrongMoves == 5) return;
- LineTo (h - 16, v + 56);
- if (wrongMoves == 6) return;
- MoveTo (h, v + 40);
- LineTo (h + 16, v + 56);
- }
-
-
- static void
- DrawMan (void)
- {
- OneDrawMan (hMid - 80, vMan);
- OneDrawMan (hMid + 80, vMan);
- }
-
-
- static void
- NextProblem (void)
- {
- StatusMesg ("\p"); /* clear message */
- wrongMoves = 0;
- DrawMan ();
- HiliteControl (button, dimHilite);
- if (word != nil)
- ZUnglueGlobSet (word); /* detach all letters */
- HiliteBlobSet (letters, inFullBlob, normalDraw);
- GenerateProblem ();
- pause = false;
- ValidRect (&wind->portRect);
- }
-
-
- /*
- * Either the word was discovered or the man hung. Set up to pause
- * until the Resume button is hit.
- */
-
- static void
- Pause (StringPtr msg)
- {
- StatusMesg (msg);
- HiliteControl (button, normalHilite); /* enable button */
- pause = true;
- }
-
-
- static pascal void
- Mouse (Point pt, long t, short mods)
- {
- BlobHandle b, r;
- ControlHandle ctl;
- short matches = 0;
-
- if (FindControl (pt, wind, &ctl))
- {
- if (TrackControl (ctl, pt, nil)) /* button hit? */
- {
- NextProblem ();
- }
- }
- else if (!pause && FindBlob (pt, letters, &b) != 0)
- {
- if (!BTrackMouse (b, pt, inDragBlob))
- return;
- for (r = FirstBlob (word); r != nil; r = NextBlob (r))
- {
- if (b == FirstBMatch (r))
- {
- ZGlueGlob (b, r);
- ++matches;
- }
- }
- HiliteBlob (b, inFullBlob, dimDraw); /* force used letter dim */
- if (matches > 0) /* letter correct */
- {
- if (BlobSetQuiet (word)) /* find answer? */
- Pause ("\pCorrect");
- }
- else /* letter incorrect */
- {
- ++wrongMoves;
- DrawMan ();
- if (wrongMoves == 7)
- {
- Pause ("\pYou Lose");
- for (r = FirstBlob (word); r != nil; r = NextBlob (r))
- {
- if (BGlob (r) == nil) /* show not-found letters */
- ZGlueGlob (FirstBMatch (r), r);
- }
- }
- }
- }
- }
-
-
- static pascal void
- Update (Boolean resized)
- {
- DrawBlobSet (word);
- DrawBlobSet (letters);
- StatusMesg (statusStr);
- DrawControls (wind);
- DrawMan ();
- }
-
-
- void
- HangInit (void)
- {
- Rect r;
- short i;
-
- SkelWindow (wind = GetDemoWind (hangWindRes),
- Mouse, /* mouse clicks */
- nil, /* key clicks */
- Update, /* updates */
- nil, /* activate/deactivate events */
- nil, /* close window */
- DoWClobber, /* dispose of window */
- nil, /* idle proc */
- false); /* irrelevant, since no idle proc */
-
- hMid = wind->portRect.right / 2;
- SetRect (&r, 0, 0, 80, 20);
- OffsetRect (&r, hMid - 40, wind->portRect.bottom - 25);
- button = NewControl (wind, &r, "\pNext", true, 0, 0, 0,
- pushButProc, 0L);
-
- SetCharBlobSize (letterSize);
- MakeDonors ();
- NextProblem ();
-
- MakeFrontWind (wind);
- }
-